package com.example.demo.exception;

import com.example.demo.common.ApiResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {
    @SneakyThrows
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        log.error("ex:" + ex);
        // 1.创建一个响应对象
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // 2.根据不同的异常类型返回不同的错误信息和HTTP状态码
        if (ex instanceof ArithmeticException) {
            //2.1数学计算异常
            ApiResponse apiResponse = ApiResponse.fail(101, "数学计算异常！");
            byte[] bytes = new ObjectMapper().writeValueAsBytes(apiResponse);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
        else if(ex instanceof MyException){
            ApiResponse apiResponse = ApiResponse.fail(((MyException) ex).getCode(), ex.getMessage());
            byte[] bytes = new ObjectMapper().writeValueAsBytes(apiResponse);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
        else {
            //2.2其它兜底异常
            ApiResponse apiResponse = ApiResponse.fail(111, "系统异常！");
            byte[] bytes = new ObjectMapper().writeValueAsBytes(apiResponse);
            DataBuffer buffer = response.bufferFactory().wrap(bytes);
            return response.writeWith(Mono.just(buffer));
        }
    }
}